package main

import (
	"encoding/json"
	"github.com/gocolly/colly"
	"io/ioutil"
	"log"
	"strings"
	"time"
)

type AreaInfo struct{
	Area string `json:"area"`
	CountryCode string `json:"country_code"`
	English string `json:"english"`
	Capital string `json:"capital"`
	Country string `json:"country"`
	LatitudeLongitude string `json:"latitude_longitude"`
	Currency string `json:"currency"`
	Language string `json:"language"`
	Utc string `json:"utc"`
	Timezone string `json:"timezone"`
	IsCountry bool `json:"is_country"`
}


var url = "http://www.24timemap.com"

var AreaInfoArr = make([]*AreaInfo, 0, 1000)
func main() {
	c := colly.NewCollector(
		// MaxDepth is 2, so only the links on the scraped page
		// and links on those pages are visited
		colly.MaxDepth(100),
		colly.Async(true),
	)
	// Limit the number of threads started by colly to two
	// when visiting links which domains' matches "*httpbin.*" glob
	c.Limit(&colly.LimitRule{
		DomainGlob:  "*24timemap.*",
		Parallelism: 5,
		Delay:      200 * time.Millisecond,
	})

	c.OnHTML("div.gjtiem_box", getItem)
	// Find and visit all links
	c.OnHTML("a[href]", func(e *colly.HTMLElement) {
		href := e.Attr("href")
		if strings.HasPrefix(href, "http://www.24timemap.com/difference") || strings.HasPrefix(href, "/difference") {
			return
		}
		if strings.HasPrefix(href, "http://www.24timemap.com/sun") || strings.HasPrefix(href, "/sun") {
			return
		}
		if strings.HasPrefix(href, "http://www.24timemap.com/moon") || strings.HasPrefix(href, "/moon") {
			return
		}
		if strings.HasPrefix(href, "http://www.24timemap.com/dst") || strings.HasPrefix(href, "/dst") {
			return
		}
		if strings.HasPrefix(href, "/") || strings.HasPrefix(href, url) {
			if err := e.Request.Visit(href); err != nil && err != colly.ErrAlreadyVisited  {
				log.Println("err visit", err.Error())
			}
		}
	})
	c.OnError(func(response *colly.Response, e error) {
		log.Println(response.Request.URL.RequestURI(), "error", e.Error())
	})
	c.OnRequest(func(r *colly.Request) {
		//fmt.Println("Visiting", r.URL)
	})

	if err := c.Visit(url); err != nil {
		log.Println(err.Error())
	}
	c.Wait()
	bytes, _ := json.Marshal(AreaInfoArr)
	log.Fatal(ioutil.WriteFile("./output/data.json", bytes, 0755))
}

func getItem(e *colly.HTMLElement) {
	e.ForEach("div.c1000", func(i int, element *colly.HTMLElement) {
		area := &AreaInfo{}
		element.ForEach(".cont b", func(i2 int, element2 *colly.HTMLElement) {
			area.Area = strings.Replace(element2.Text, "首都：","",-1)
			if strings.HasPrefix(element2.Text, "首都：")  {
				area.Capital = area.Area
			}
		})
		element.ForEach(".cont1 ul li", func(i2 int, element2 *colly.HTMLElement) {
			text := element2.ChildText("p")
			switch strings.Replace(element2.ChildText("em"), "：", "", -1)  {
			case "英文名":
				area.English =text
			case "首都":
				area.IsCountry = true
				area.Capital = text
			case "国家":
				area.Country = text
			case "国家区号":
				area.CountryCode = text
			case "纬度/经度":
				area.LatitudeLongitude = text
			case "货币":
				area.Currency = text
			case "语言":
				area.Language = text
			case "时区":
				area.Utc = text
			case "时区划分":
				area.Timezone = text
			}
		})
		AreaInfoArr = append(AreaInfoArr, area)
	})
}